Взгляд снизу вверх или Ubuntu Server для разработчика электроники. Часть 2 / Хабр

您所在的位置:网站首页 cpp strlen Взгляд снизу вверх или Ubuntu Server для разработчика электроники. Часть 2 / Хабр

Взгляд снизу вверх или Ubuntu Server для разработчика электроники. Часть 2 / Хабр

#Взгляд снизу вверх или Ubuntu Server для разработчика электроники. Часть 2 / Хабр| 来源: 网络整理| 查看: 265

Роль демонов в Linux похожа на роль служб в Windows. Это программы, которые живут в фоновом режиме и делают всякую периферическую работу. Всё начинается с systemd — программы, которая запускается первой, имеет соответственно PID=1, и запускает все другие фоновые задачи через скрипты. Поковырявшись в Ubuntu, я удивился насколько много всего внутри построено на скриптах. Вы уже видели, как меняется статический IP, настраиваются программы, простой коррекцией файлов в текстовом редакторе.

Выполнив

ps -el Вы увидите список запущенных программ с их PID. PID — это обязательный идентификатор запущенной программы, по которому за этой программой следит ОС. В крайней ситуации, можно грохнуть программу по этому PID из терминала — пишите kill и PID (может пригодиться для отладки).

Так вот, при запуске демона исполняется скрипт, в котором указано когда и как программу нужно запустить, как её остановить или перезапустить. Чтобы демон работал нормально, программа при запуске должна сохранить в файл, путь к которому указан в скрипте, свой PID и перейти в другой поток (в фоновый режим).

Пособие по демону меня ввело в грусть и тоску. Сильно упростив демона, я его превратил в утилиту для запуска любой программы. Но обязательная часть не поменялась. Помимо этого, он ведет лог, чтобы проверить, если вдруг что.

код daemonvoid SetPidFile(char* Filename) { FILE* f; f = fopen(Filename, "w+"); if (f) { fprintf(f, "%u", getpid()); fclose(f); } } int main( int argc, char** argv ) { char toolfile[32]; char folder[32]; intptr_t ret; FILE* logfile; if( argc!=3 ) { printf( "Write address of the program and name: /home/ubuntu/tool/ tool\n"); return -1; } pid_t pid, sid; pid = fork(); if (pid < 0) { sleep(1); return -1; } //We got a good pid, Close the Parent Process if (pid > 0) { return 0; } //Create a new Signature Id for our child sid = setsid(); if (sid < 0) { return -1; } //Change File Mask umask(0); //Save PID memcpy( toolfile, argv[0], strlen(argv[0]) ); memcpy( toolfile + strlen(argv[0]), ".log", 4 ); memset( toolfile + strlen(argv[0]) + 4, 0, 1 ); printf( "Daemon:: log to:%s\n", toolfile ); logfile = fopen( toolfile, "w" ); fprintf( logfile, "Daemon:: started with 0=%s 1=%s 2=%s\n", argv[0], argv[1], argv[2] ); memset( toolfile, 0, 32 ); memcpy( toolfile, argv[0], strlen(argv[0]) ); memcpy( toolfile + strlen(argv[0]), ".pid", 4 ); memset( toolfile + strlen(argv[0]) + 4, 0, 1 ); SetPidFile( toolfile ); fprintf( logfile, "Daemon:: PID=%u saved in the %s\n", getpid(), toolfile ); memset( folder, 0, 32 ); memcpy( folder, argv[1], strlen(argv[1]) ); fflush ( logfile ); memset( toolfile, 0, 32 ); memcpy( toolfile, folder, strlen(argv[1]) ); memset( toolfile + strlen(argv[1]), '/', 1 ); memcpy( toolfile + strlen(argv[1]) + 1, argv[2], strlen(argv[2]) ); //Change Directory //If we cant find the directory we exit with failure. if ((chdir(folder)) < 0) { fprintf( logfile, "Daemon:: Program folder was not found:%s\n", folder ); fclose( logfile ); return -1; } //Close Standard File Descriptors close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); fprintf( logfile, "Daemon:: Program started\n" ); fflush ( logfile ); ret = execl( toolfile, folder, NULL ); if( ret==-1 ) { fprintf( logfile, "Daemon:: execl error: %s. File=%s Folder=%s\n", strerror(errno), toolfile, folder ); fclose( logfile ); return -1; } fprintf( logfile, "Daemon:: closed\n" ); fclose( logfile ); return 0; } Компилируем демона.

На данный момент в нашем рабочем каталоге, допустим /home/ubuntu/daemon/, имеем:

daemon — программа демона prgr — программа prgr.strt — скрипт, который нужно выполнить до запуска программы (если надо) prgr.stop — скрипт, который нужно выполнить для остановки программы (если надо)

Нужно разрешить программам работать:

sudo chmod 755 ./tool sudo chmod 755 ./daemon Теперь нужен скрипт для systemd Делаем sudo nano /etc/systemd/system/mydaemon.service и записываем туда наш скрипт.

mydaemon.service[Unit] Description=my service After=network.target After=isc-dhcp-server.service [Service] Type=forking PIDFile=/home/ubuntu/daemon/daemon.pid ExecStartPre=/bin/sh /home/ubuntu/daemon/prgr.strt ExecStart=/home/ubuntu/daemon/daemon /home/ubuntu/daemon/prgr prgr ExecStop=/bin/sh /home/ubuntu/daemon/prgr.stop Restart=always TimeoutSec=5 [Install] WantedBy=multi-user.target В скрипте кратко: Description — краткое название-описание After — что требуется для запуска Type=forking — systemd предполагает, что служба запускается однократно и процесс разветвляется с завершением родительского процесса. PIDFile — файл с PID программы из демона ExecStartPre — до запуска программы ExecStart — программа с параметрами ExecStop — как остановить WantedBy — уровень, на котором запускать

Теперь можно попробовать всё запустить. Пишем

systemctl daemon-reload systemctl status mydaemon Если всё без ошибок, то запускаем: systemctl start mydaemon После этого смотрите лог демона, всё должно поехать. Чтобы работала автозагрузка systemctl enable mydaemon


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3